<template>
  <div class="app-container">
    <div class="box" ref="box" :style="{ height: BoxHeight + 'px' }">
      <div class="top">
        <el-select
          style="width: 15%; margin-right: 15px"
          v-model="sourceId"
          placeholder="请选择数据库"
          clearable
          @change="changeSource"
        >
          <el-option
            v-for="dict in listDatasource"
            :key="dict.dataSourceName"
            :label="dict.dataSourceName"
            :value="dict.id"
          />
        </el-select>

        <el-select
          style="width: 15%; margin-right: 15px"
          v-model="databaseName"
          placeholder="请选择源库"
          clearable
        >
          <el-option
            v-for="item in listTableData"
            :key="item"
            :label="item"
            :value="item"
          />
        </el-select>

        <el-button @click="executeSql" type="success" style="width: 10%"
          >+ 执行SQL</el-button
        >
        <el-button @click="handleHistory" type="info">执行历史</el-button>
      </div>
      <div class="middle">
        <div class="left">
          <ul
            class="databaseBox"
            v-if="sourceId && sourceDatabaseHistoryList.length > 0"
          >
            <li
              class="database-item"
              v-for="item in sourceDatabaseHistoryList"
              :key="item.createTime"
              @click="selectListdatabase(item)"
            >
              <a href="#" title="查看sql">
                <div class="sql-status"></div>
                <p>{{ item.dataSourceName }}</p>
                <pre class="historySql">{{ item.sqlContext }}</pre>
                <p style="color: #666; font-size: 12px">
                  执行时间：{{ item.createTime }}
                </p>
              </a>
              <!-- <a href="#" class="item-text" :title="item">{{ item }}</a> -->
            </li>
          </ul>
          <el-empty v-else description="暂无历史" :image-size="150"></el-empty>
        </div>
        <div class="right" ref="right">
          <editor
            :key="offsetHeight"
            @init="editorInit"
            ref="aceEditor"
            v-model="sql"
            width="100%"
            :height="offsetHeight"
            lang="sql"
            theme="dracula"
            :options="{
              enableBasicAutocompletion: true,
              enableSnippets: true,
              enableLiveAutocompletion: true,
              showPrintMargin: false, //去除编辑器里的竖线
              tabSize: 4,
              fontSize: 16,
            }"
          />
          <div
            class="history"
            ref="historyEl"
            :style="{ height: historyBox + 'px' }"
          >
            <div class="line" @mousedown.stop.prevent="drag"></div>
            <div class="history-list">
              <div
                class="history-item"
                v-for="(item, index) in historyList"
                :key="index"
              >
                <div class="history-item-title">
                  <p
                    :style="{
                      color: item.status == 'success' ? '#fff' : 'red',
                    }"
                    class="history-item-title-text"
                  >
                    {{ item.createTime }}：{{ item.title }}
                  </p>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
    <el-dialog title="sql查看" :visible.sync="dialogStackVisible" width="75%">
      <el-button style="margin-bottom: 10px" type="primary" @click="copyDdl"
        >复制</el-button
      >
      <editor
        @init="editorInit"
        ref="aceEditor"
        v-model="stackErrorsMsg"
        width="100%"
        :height="400"
        lang="sql"
        theme="dracula"
        :options="{
          enableBasicAutocompletion: true,
          enableSnippets: true,
          enableLiveAutocompletion: true,
          showPrintMargin: false, //去除编辑器里的竖线
          tabSize: 4,
          fontSize: 16,
          readOnly: true,
        }"
      />
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="dialogStackVisible = false"
          >确 定</el-button
        >
      </span>
    </el-dialog>
  </div>
</template>

<script>
import {
  listDatasourceInfo,
  databaseListData,
} from "@/api/console/datasourceInfo";
import { sqlTaskExecuteSql, sqlTaskList } from "@/api/console/executeSql";

export default {
  name: "executeSql",
  components: { editor: require("vue2-ace-editor") },
  data() {
    return {
      stackErrorsMsg: "",
      dialogStackVisible: false,
      sourceId: null,
      databaseId: null,
      listDatasource: [],
      listTableData: [],
      active: null,
      offsetHeight: null,
      BoxHeight: null,
      sql: null,
      startWidth: 0,
      startHeight: 0,
      startX: 0,
      startY: 0,
      boxWidth: 0,
      historyBox: 140,
      dragging: false,
      historyList: [],
      rightBoxHeight: 0,
      databaseName: null,
      sourceDatabaseHistoryList: [],
    };
  },
  async mounted() {
    let res = await listDatasourceInfo({
      pgNum: 1,
      pgSize: 999,
    });
    this.listDatasource = res.rows;
    this.offsetHeight = this.$refs.right.offsetHeight - this.historyBox;
    this.BoxHeight = this.$refs.box.offsetHeight;
    this.rightBoxHeight = this.$refs.right.offsetHeight;
  },
  methods: {
    copyDdl() {
      const dom = document.createElement("input");
      dom.value = this.stackErrorsMsg;
      document.body.appendChild(dom);
      dom.select();
      document.execCommand("copy");
      document.body.removeChild(dom);
      this.$message.success("复制成功");
    },
    handleHistory() {
      this.$router.push({
        path: "/sqlHistory/index",
      });
    },
    drag(e) {
      e.preventDefault();
      this.dragging = true;
      const codeBoxEl = this.$refs.historyEl;
      this.startHeight = codeBoxEl.offsetHeight;
      this.startY = e.clientY;
      document.addEventListener("mousemove", this.doDrag);
      document.addEventListener("mouseup", this.stopDrag);
    },
    doDrag(event) {
      if (this.dragging) {
        this.historyBox = this.startHeight + (event.clientY - this.startY) * -1;
        this.offsetHeight = this.rightBoxHeight - this.historyBox;
        if (this.historyBox >= this.rightBoxHeight - 80) {
          this.historyBox = this.rightBoxHeight - 80;
          this.offsetHeight = 80;
        }
        if (this.historyBox < 80) {
          this.historyBox = 80;
          this.offsetHeight = this.rightBoxHeight - 80;
        }
      }
    },
    stopDrag() {
      this.dragging = false;
      document.removeEventListener("mousemove", this.doDrag);
      document.removeEventListener("mouseup", this.stopDrag);
    },
    editorInit() {
      // 初始化
      require("brace/ext/language_tools");
      require("brace/ext/beautify");
      require("brace/ext/error_marker");
      require("brace/ext/searchbox");
      require("brace/ext/split");
      require("brace/snippets/sql");
      require("brace/mode/sql");
      require("brace/theme/dracula");
    },
    createDatabase() {
      this.$router.push({
        path: "/datasourceInfo",
      });
    },
    selectListdatabase(item) {
      this.active = item;
      this.stackErrorsMsg = item.sqlContext;
      this.dialogStackVisible = true;
    },
    removeSpaces(str) {
      return str.replace(/\s+/g, "");
    },
    async changeSource(v) {
      if (!v) {
        this.databaseName = null;
        return;
      }
      this.databaseId = v;
      const item = this.listDatasource.find((item) => item.id == v);
      let res = await databaseListData({
        id: v,
      });
      this.listTableData = res.data.data;
      res = await sqlTaskList({
        pgNum: 1,
        pgSize: 999,
        dataSourceName: item.dataSourceName,
      });
      this.sourceDatabaseHistoryList = res.rows;
    },
    async executeSql() {
      let that = this;
      if (!this.sourceId) {
        this.$message.warning("请选择数据库");
        return;
      }
      if (this.removeSpaces(this.sql).length == 0) {
        return;
      }
      try {
        this.$modal
          .confirm("是否确认执行SQL？")
          .then(function () {
            return sqlTaskExecuteSql({
              datasourceId: that.databaseId,
              sqlContext: that.sql,
              databaseName: that.databaseName,
            });
          })
          .then(async (res) => {
            this.historyList.push({
              createTime: new Date().toLocaleString(),
              title: res.data.msg,
              status: res.data.code == "200" ? "success" : "error",
            });
            this.changeSource(this.databaseId);
            this.$nextTick(() => {
              let scrollElem = this.$refs.historyEl;
              scrollElem.scrollTo({
                top: scrollElem.scrollHeight,
                behavior: "smooth",
              });
            });
          });
      } catch (error) {
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.app-container {
  height: 100%;
  min-width: 1100px;
}

.box {
  width: 100%;
  height: 100%;
  border: 1px solid #aaa;
  display: flex;
  flex-direction: column;

  .top {
    width: 100%;
    height: 45px;
    border-bottom: 1px solid #000;
    display: flex;
    align-items: center;
    padding: 0 15px;
  }

  .middle {
    height: calc(100% - 45px);
    display: flex;
  }

  .left {
    width: 250px;
    text-align: center;
    padding: 10px 0;
    background: rgba(249, 249, 249);

    .databaseBox {
      list-style-type: none;
      width: 100%;
      text-align: left;
      margin: 0 auto 10px auto;
      padding: 0;
      overflow-y: auto;
      height: 100%;

      p {
        margin: 0;
        padding: 0;
      }

      .database-item {
        padding: 8px;
        cursor: pointer;
        overflow: auto;
        width: 100%;
        border-bottom: 1px solid #ccc;
        position: relative;
        //  .sql-status {
        //   position: absolute;
        //   right: 15px;
        //   width: 7px;
        //   height: 7px;
        //   top: 5px;
        //   background-color: red;
        //   border-radius: 50%;
        // }
        .item-text {
          color: #444;
          font-size: 15px;
          overflow: hidden;
          white-space: nowrap;
          text-overflow: ellipsis;
          display: block;
          width: 100%;
          color: rgba($color: #111, $alpha: 0.8);
        }
      }

      .database-item:hover {
        background: rgba(240, 240, 240, 0.8);
      }
    }
    .notSourceIdTips {
      padding: 0 8px;
      text-align: left;
      p {
        letter-spacing: 1px;
        color: #444;
        font-size: 14px;
      }
    }
  }
  .right {
    width: 100%;
    height: 100%;
    position: relative;

    .history {
      height: 140px;
      background-color: #000;
      width: 100%;
      position: absolute;
      bottom: 0;
      overflow: auto;
      z-index: 999;
      border: 1px solid rgba(250, 250, 250, 0.6);

      .line {
        width: 100%;
        height: 3px;
      }

      .line:hover {
        background-color: rgb(0, 120, 212);
        cursor: row-resize;
      }
    }
  }
}

::v-deep .el-divider--horizontal {
  margin: 15px 0;
}

.active {
  background-color: rgb(180, 180, 180);

  a {
    color: #fff !important;
  }
}

.active:hover {
  background-color: rgb(180, 180, 180) !important;
}

.history-item-title-text {
  font-size: 14px;
  padding: 0 10px;
}

.historySql {
  white-space: nowrap; /* 不换行 */
  overflow: hidden; /* 隐藏溢出内容 */
  text-overflow: ellipsis;
  -webkit-line-clamp: 3;
  height: 20px;
}
</style>
